home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 078 (1990-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 078 (1990-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / MSH / src / messyfmt.c < prev    next >
C/C++ Source or Header  |  1990-06-17  |  10KB  |  371 lines

  1. /*
  2.  * $Id: messyfmt.c,v 1.30 90/06/04 23:20:13 Rhialto Rel $
  3.  * $Log:    messyfmt.c,v $
  4.  * Revision 1.30  90/06/04  23:20:13  Rhialto
  5.  * Release 1 Patch 3
  6.  * 
  7.  * MESSYFMT.C
  8.  *
  9.  * Formats a disk. Low-level formatting can also be done by mounting a file
  10.  * system and using the AmigaDOS format command.
  11.  *
  12.  * This code is (C) Copyright 1989,1990 by Olaf Seibert. All rights reserved.
  13.  * May not be used or copied without a licence.
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include "han.h"
  18. extern int    Enable_Abort;
  19.  
  20. ulong        BootBlock[] = {
  21.     0xEB349049, 0x424D2020, 0x332E3200, 0x02020100,    /* ...IBM  3.2..... */
  22.     0x027000A0, 0x05F90300, 0x09000200, 0x00000000,
  23.     0x00000000, 0x00000000, 0x00000000, 0x0000000F,
  24.     0x00000000, 0x0100FA33, 0xC08ED0BC, 0x007C1607,
  25.     0xBB780036, 0xC5371E56, 0x1653BF2B, 0x7CB90B00,
  26.     0xFCAC2680, 0x3D007403, 0x268A05AA, 0x8AC4E2F1,
  27.     0x061F8947, 0x02C7072B, 0x7CFBCD13, 0x7267A010,
  28.     0x7C98F726, 0x167C0306, 0x1C7C0306, 0x0E7CA33F,
  29.     0x7CA3377C, 0xB82000F7, 0x26117C8B, 0x1E0B7C03,
  30.     0xC348F7F3, 0x0106377C, 0xBB0005A1, 0x3F7CE896,
  31.     0x00B80102, 0xE8AA0072, 0x198BFBB9, 0x0B00BECD,
  32.     0x7DF3A675, 0x0D8D7F20, 0xBED87DB9, 0x0B00F3A6,
  33.     0x7418BE6E, 0x7DE86100, 0x32E4CD16, 0x5E1F8F04,
  34.     0x8F4402CD, 0x19BEB77D, 0xEBEBA11C, 0x0533D2F7,
  35.     0x360B7CFE, 0xC0A23C7C, 0xA1377CA3, 0x3D7CBB00,
  36.     0x07A1377C, 0xE84000A1, 0x187C2A06, 0x3B7C4050,
  37.     0xE84E0058, 0x72CF2806, 0x3C7C760C, 0x0106377C,
  38.     0xF7260B7C, 0x03D8EBD9, 0x8A2E157C, 0x8A16FD7D,
  39.     0x8B1E3D7C, 0xEA000070, 0x00AC0AC0, 0x7422B40E,
  40.     0xBB0700CD, 0x10EBF233, 0xD2F73618, 0x7CFEC288,
  41.     0x163B7C33, 0xD2F7361A, 0x7C88162A, 0x7CA3397C,
  42.     0xC3B4028B, 0x16397CB1, 0x06D2E60A, 0x363B7C8B,
  43.     0xCA86E98A, 0x16FD7D8A, 0x362A7CCD, 0x13C30D0A,
  44.     0x4E6F6E2D, 0x53797374, 0x656D2064, 0x69736B20,    /* Non-System disk  */
  45.     0x6F722064, 0x69736B20, 0x6572726F, 0x720D0A52,    /* or disk error..R */
  46.     0x65706C61, 0x63652061, 0x6E642073, 0x7472696B,    /* eplace and strik */
  47.     0x6520616E, 0x79206B65, 0x79207768, 0x656E2072,    /* e any key when r */
  48.     0x65616479, 0x0D0A000D, 0x0A446973, 0x6B20426F,    /* eady.....Disk Bo */
  49.     0x6F742066, 0x61696C75, 0x72650D0A, 0x0049424D,    /* ot failure...IBM */
  50.     0x42494F20, 0x20434F4D, 0x49424D44, 0x4F532020,    /* BIO    COMIBMDOS   */
  51.     0x434F4D00, 0x00000000, 0x00000000, 0x00000000,    /* COM............. */
  52.     0x00000000, 0x00000000, 0x00000000, 0x000055AA,
  53. };
  54.  
  55. byte           *DiskTrack;
  56. long        TrackSize;
  57. int        Track;
  58. int        LowTrack;
  59. word        nsides;
  60. struct IOExtTD *TDReq,
  61.            *CreateExtIO();
  62. char           *Device;
  63.  
  64. int
  65. todigit(c)
  66. register char    c;
  67. {
  68.     if ((c -= '0') < 0 || c > ('F' - '0'))
  69.     return 42;
  70.  
  71.     if (c >= ('A' - '0')) {
  72.     c -= 'A' - '9' - 1;
  73.     }
  74.     return c;
  75. }
  76.  
  77. long
  78. ntoi(str)
  79. register char  *str;
  80. {
  81.     register long   total = 0;
  82.     register long   value;
  83.     register int    digit;
  84.     register int    base;
  85.  
  86.     /* First determine the base */
  87. number:
  88.     if (*str == '0') {
  89.     if (*++str == 'x') {    /* 0x means hexadecimal */
  90.         base = 16;
  91.         str++;
  92.     } else {
  93.         base = 8;        /* Otherwise, 0 means octal */
  94.     }
  95.     } else {
  96.     base = 10;        /* and any other digit means decimal */
  97.     }
  98.  
  99.     value = 0;
  100.     while ((digit = todigit(*str)) < base) {
  101.     value *= base;
  102.     value += digit;
  103.     str++;
  104.     }
  105.  
  106. suffix:
  107.     switch (*str++) {
  108.     case 'm':                   /* scale with megabytes */
  109.     value *= 1024L * 1024;
  110.     goto suffix;
  111.     case 'k':                   /* scale with kilobytes */
  112.     value *= 1024;
  113.     goto suffix;
  114.     case 's':                   /* scale with sectors */
  115.     value *= TD_SECTOR;    /* or maybe even kilosectors! */
  116.     goto suffix;
  117.     case 'b':                   /* scale with bytes */
  118.     goto suffix;
  119.     }
  120.     str--;
  121.  
  122.     total += value;
  123.  
  124.     if (*str >= '0' && *str <= '9')
  125.     goto number;        /* Allow 10k512, recursion eliminated */
  126.  
  127.     return total;
  128. }
  129.  
  130. word
  131. input(question, defval)
  132. char           *question;
  133. word        defval;
  134. {
  135.     char        buf[80];
  136.  
  137.     printf("%s? [%d] ", question, defval);
  138.     fflush(stdout);
  139.     if (fgets(buf, sizeof (buf) - 1, stdin)) {
  140.     if (buf[0] && buf[0] != '\n')
  141.         defval = ntoi(buf);
  142.     }
  143.     return defval;
  144. }
  145.  
  146. void
  147. PutWord(address, value)
  148. register byte  *address;
  149. register word    value;
  150. {
  151.     address[0] = value;
  152.     address[1] = value >> 8;
  153. }
  154.  
  155. word
  156. SetWord(address, question, value)
  157. byte           *address;
  158. char           *question;
  159. word        value;
  160. {
  161.     value = input(question, value);
  162.     PutWord(address, value);
  163.  
  164.     return value;
  165. }
  166.  
  167. byte
  168. SetByte(address, question, value)
  169. byte           *address;
  170. char           *question;
  171. word        value;
  172. {
  173.     value = input(question, value);
  174.     return *address = value;
  175. }
  176.  
  177. byte           *
  178. MaybeWrite(block)
  179. byte           *block;
  180. {
  181.     while (block >= (DiskTrack + TrackSize)) {
  182.     int        t,
  183.             s;
  184.  
  185.     t = Track / nsides;
  186.     s = Track % nsides;
  187.     printf("  Writing cylinder %3d side %d...\r", t, s);
  188.     fflush(stdout);
  189.     TDReq->iotd_Req.io_Command = TD_FORMAT;
  190.     TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
  191.     TDReq->iotd_Req.io_Length = TrackSize;
  192.     TDReq->iotd_Req.io_Offset = TrackSize * Track;
  193.     DoIO(TDReq);
  194.     if (TDReq->iotd_Req.io_Error) {
  195.         printf(" Write error %d on cylinder %d side %d.\n",
  196.            TDReq->iotd_Req.io_Error, t, s);
  197.     }
  198.     TDReq->iotd_Req.io_Command = CMD_UPDATE;
  199.     DoIO(TDReq);
  200.     if (TDReq->iotd_Req.io_Error) {
  201.         printf("Update error %d on cylinder %d side %d.\n",
  202.            TDReq->iotd_Req.io_Error, t, s);
  203.     }
  204.     TDReq->iotd_Req.io_Command = CMD_CLEAR;
  205.     DoIO(TDReq);
  206.  
  207.     printf("  Read\r");
  208.     fflush(stdout);
  209.     TDReq->iotd_Req.io_Command = CMD_READ;
  210.     TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
  211.     TDReq->iotd_Req.io_Length = TrackSize;
  212.     TDReq->iotd_Req.io_Offset = TrackSize * Track;
  213.     DoIO(TDReq);
  214.     if (TDReq->iotd_Req.io_Error) {
  215.         printf("  Read error %d on cylinder %d side %d.\n",
  216.            TDReq->iotd_Req.io_Error, t, s);
  217.     }
  218.     setmem(DiskTrack, (int) TrackSize, 0);
  219.     Track++;
  220.     if ((block -= TrackSize) < DiskTrack)
  221.         block = DiskTrack;
  222.     }
  223.     return block;
  224. }
  225.  
  226. main(argc, argv)
  227. int        argc;
  228. char          **argv;
  229. {
  230.     struct MsgPort *port,
  231.            *CreatePort();
  232.     byte       *diskBlock;
  233.     long        unitNr;
  234.     int         i;
  235.     word        bps = MS_BPS,
  236.             spt = MS_SPT;
  237.     word        res,
  238.             nfats,
  239.             spf,
  240.             nsects,
  241.             ncylinders,
  242.             ndirs,
  243.             wholeDisk,
  244.             clearFat,
  245.             endtrack;
  246.  
  247.     if (argc < 2) {
  248.     printf("Usage: %s <unitnr> <device>\n"
  249.            "Formats a messydos volume in any desired shape.\n",
  250.            argv[0]);
  251.     exit(1);
  252.     }
  253.     Enable_Abort = 0;
  254.     unitNr = ntoi(argv[1]);
  255.     if (argc > 2)
  256.     Device = argv[2];
  257.     else
  258.     Device = "messydisk.device";
  259.  
  260.     if (!(port = CreatePort(NULL, 0L))) {
  261.     puts("No memory for replyport");
  262.     goto abort1;
  263.     }
  264.     if (!(TDReq = CreateExtIO(port, (long) sizeof (*TDReq)))) {
  265.     puts("No memory for I/O request");
  266.     goto abort2;
  267.     }
  268.     if (OpenDevice(Device, unitNr, TDReq, 0L)) {
  269.     printf("Cannot OpenDevice %s\n", Device);
  270.     goto abort3;
  271.     }
  272.  
  273.     printf("Preparing to format disk in %s unit #%d.\n\n", Device, (int) unitNr);
  274.     bps = input("Bytes per sector", bps);
  275.     spt = input("Sectors per track", spt);
  276.     TrackSize = bps * spt;
  277.     nsides = input("Number of sides", MS_NSIDES);
  278.     Track = input("Starting cylinder", 0);
  279.     Track *= nsides;
  280.     ncylinders = input("Number of cylinders", 80);
  281.     endtrack = Track + nsides * ncylinders;
  282.  
  283.     if ((DiskTrack = AllocMem(TrackSize,
  284.             MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR)) == NULL) {
  285.     puts("No memory for track buffer");
  286.     goto abort4;
  287.     }
  288.     CopyMem(BootBlock, DiskTrack, (long) sizeof (BootBlock));
  289.  
  290.     PutWord(DiskTrack + 0x0b, bps);
  291.     SetByte(DiskTrack + 0x0d, "Sectors per cluster", MS_SPC);
  292.     res = SetWord(DiskTrack + 0x0e, "Bootsectors", MS_RES);
  293.     nfats = SetByte(DiskTrack + 0x10, "Number of FAT copies", MS_NFATS);
  294.     ndirs = SetWord(DiskTrack + 0x11, "Root directory entries", MS_NDIRS);
  295.     nsects = SetWord(DiskTrack + 0x13, "Total number of sectors", spt * ncylinders * nsides);
  296.     SetByte(DiskTrack + 0x15, "Media byte", 0xF9);
  297.     spf = SetWord(DiskTrack + 0x16, "Sectors per FAT", MS_SPF);
  298.     PutWord(DiskTrack + 0x18, spt);
  299.     PutWord(DiskTrack + 0x1a, nsides);
  300.     SetWord(DiskTrack + 0x1c, "Number of hidden sectors", 0);
  301.  
  302.     wholeDisk = input("Format whole disk (enter 1)", 0);
  303.     if (!wholeDisk)
  304.     clearFat = input("Write how much then?\n"
  305.              " (enter 0 for just the bootblock)\n"
  306.              " (enter 1 for FAT and root directory as well)", 0);
  307.  
  308.     if (input("Are you sure? (enter 42)", 0) != 42)
  309.     goto abort5;
  310.  
  311.     if (Chk_Abort())
  312.     goto abort5;
  313.  
  314.     if (!wholeDisk && !clearFat) {
  315.     puts("Writing bootblock only.");
  316.     TDReq->iotd_Req.io_Command = CMD_WRITE;
  317.     TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
  318.     TDReq->iotd_Req.io_Length = sizeof (BootBlock);
  319.     TDReq->iotd_Req.io_Offset = 0;
  320.     DoIO(TDReq);
  321.     TDReq->iotd_Req.io_Command = CMD_UPDATE;
  322.     DoIO(TDReq);
  323.  
  324.     goto done;
  325.     }
  326.  
  327.     /* Go to first FAT */
  328.     diskBlock = MaybeWrite(DiskTrack + bps * res);
  329.     for (i = 0; i < nfats; i++) {
  330.     diskBlock[0] = 0xF9;
  331.     diskBlock[1] = 0xFF;
  332.     diskBlock[2] = 0xFF;
  333.     diskBlock = MaybeWrite(diskBlock + bps * spf);  /* Next FAT */
  334.     }
  335.  
  336.     /* Clear entire directory */
  337.     diskBlock = MaybeWrite(diskBlock + ndirs * MS_DIRENTSIZE);
  338.     MaybeWrite(DiskTrack + TrackSize);  /* Force a write */
  339.  
  340.     ncylinders *= nsides;
  341.     if (wholeDisk) {
  342.     while (Track < ncylinders) {
  343.         MaybeWrite(DiskTrack + TrackSize);  /* Write an empty track */
  344.         if (Chk_Abort())
  345.         break;
  346.     }
  347.     }
  348.  
  349. done:
  350.     TDReq->iotd_Req.io_Command = TD_MOTOR;
  351.     TDReq->iotd_Req.io_Length = 0;
  352.     DoIO(TDReq);
  353.  
  354.     printf("\n\nNow remove the disk from the drive (or use DiskChange).\n");
  355.  
  356. abort5:
  357.     FreeMem(DiskTrack, TrackSize);
  358. abort4:
  359.     CloseDevice(TDReq);
  360. abort3:
  361.     DeleteExtIO(TDReq);
  362. abort2:
  363.     DeletePort(port);
  364. abort1:;
  365.  
  366. }
  367.  
  368. _wb_parse()
  369. {
  370. }
  371.